Skip to content

Conversation

@sebastianplesciuc
Copy link

Issue # 36567

Closes #36567

Reason for this change

When using nodeModules with pnpm, CDK creates a pnpm-workspace.yaml in the bundling directory (added in #21911). This causes pnpm to treat the bundling directory as a standalone workspace root, which prevents it from inheriting .npmrc configuration from parent directories. This breaks authentication for packages from private registries.

Description of changes

When pnpm is detected and nodeModules is specified, copy the project's .npmrc (if it exists) to the bundling directory alongside pnpm-workspace.yaml. This allows pnpm to find auth tokens for private registries.

Describe any new or updated permissions being added

N/A

Description of how you validated changes

  • Added unit test 'pnpm with nodeModules copies .npmrc for private registry authentication'
  • All existing tests pass (120/120)

Checklist


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@github-actions github-actions bot added beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK bug This issue is a bug. effort/medium Medium work item – several days of effort labels Jan 6, 2026
@aws-cdk-automation aws-cdk-automation requested a review from a team January 6, 2026 10:14
@github-actions github-actions bot added the p2 label Jan 6, 2026
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pull request linter fails with the following errors:

❌ Fixes must contain a change to an integration test file and the resulting snapshot.

If you believe this pull request should receive an exemption, please comment and provide a justification. A comment requesting an exemption should contain the text Exemption Request. Additionally, if clarification is needed, add Clarification Request to a comment.

✅ A exemption request has been requested. Please wait for a maintainer's review.

@sebastianplesciuc
Copy link
Author

Exemption Request

This fix modifies the Docker bundling command to copy .npmrc when using pnpm with nodeModules. Integration test snapshots only capture CloudFormation templates, not bundling commands - the bundling command is executed at synth time and only the resulting asset hash appears in the snapshot.

The fix is covered by a unit test that verifies the bundling command includes cp .npmrc when .npmrc exists. The existing integ.dependencies-pnpm.ts test validates pnpm bundling works correctly.

@aws-cdk-automation aws-cdk-automation added the pr-linter/exemption-requested The contributor has requested an exemption to the PR Linter feedback. label Jan 6, 2026
@sebastianplesciuc
Copy link
Author

PR Update: Changed approach from file copy to base64 encoding

The initial implementation failed the integration test because it tried to copy .npmrc using a relative path. In Docker bundling, only projectRoot is mounted as /asset-input, so when .npmrc is outside projectRoot (common in pnpm monorepos where .npmrc is at workspace root), the file copy fails with "No such file or directory".

New approach

  • Read .npmrc content at CDK synth time
  • Base64 encode it and embed in the bundling command
  • Decode at runtime using echo '<base64>' | base64 -d > .npmrc

This works because:

  1. The file is read during synth (when it's accessible), not during Docker bundling
  2. Base64 avoids shell escaping issues with special characters in .npmrc (quotes, tokens, etc.)
  3. Works for both local and Docker bundling

Testing

  • Unit tests pass
  • Integration test (integ.dependencies-pnpm.js) ran successfully locally and snapshot is unchanged
  • Added .testnpmrc fixture file for unit testing

@aws-cdk-automation aws-cdk-automation added the pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member. label Jan 12, 2026
Copy link
Contributor

@lpizzinidev lpizzinidev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ty!

});
});

test('pnpm with nodeModules writes .npmrc using base64 for private registry authentication', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit. Can you please add coverage for the win32 platform?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Added and re-based.

…uthentication

When using nodeModules with pnpm, CDK creates a pnpm-workspace.yaml which
prevents pnpm from inheriting .npmrc from parent directories. This fix
copies the project's .npmrc to the bundling directory when it exists.

Fixes aws#36567
@sebastianplesciuc sebastianplesciuc force-pushed the sebastianplesciuc/fix-lambda-nodejs-pnpm-npmrc branch from 76734a4 to 9eba1b9 Compare February 5, 2026 12:14
assetHashType: AssetHashType.OUTPUT,
bundling: expect.objectContaining({
command: expect.arrayContaining([
expect.stringContaining(`echo '${npmrcBase64}' | base64 -d`),
Copy link
Contributor

@lpizzinidev lpizzinidev Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird. I'd expect this to be powershell -Command .... I suspect we should

Bundling.bundle(stack, { platform: 'win32', ... });

Instead of spyOn(os, 'platform')?
Am I missing something?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's completely my fault for rushing this and trying to copy the test from 158. I'll try and fix this today. Thanks for catching it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. So digging into this, the BundlingProps interface doesn't currently expose a platform option - the platform is detected at runtime via os.platform(). The existing win32 test ("esbuild with Windows paths") uses the same jest.spyOn(os, 'platform') pattern.

The reason I missed the bash thing is because only local bundling on Windows will run the PowerShell command, in Docker it will always be bash. I'll try and make a cheeky test by calling tryBundle() directly to force local bundling and mock spawnSync to capture the cmd /c call.

Copy link
Contributor

@lpizzinidev lpizzinidev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for following up!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK bug This issue is a bug. effort/medium Medium work item – several days of effort p2 pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member. pr-linter/exemption-requested The contributor has requested an exemption to the PR Linter feedback.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(lambda-nodejs): nodeModules with pnpm doesn't inherit project .npmrc for private registry authentication

3 participants